package com.ok.common.utils

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.wifi.WifiManager
import android.os.Build
import com.ok.common.base.AppContext
import java.net.Inet4Address
import java.net.NetworkInterface


object NetUtils {

    private const val TAG = "NetUtils"

    fun isNetworkConnected(): Boolean {
        val context = AppContext.applicationContext
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            connectivityManager.activeNetwork ?: return false
            connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)?.run {
                hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && (hasTransport(
                    NetworkCapabilities.TRANSPORT_WIFI
                ) || hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
            } ?: false
        } else {
            @Suppress("DEPRECATION")
            connectivityManager.activeNetworkInfo?.run { isConnectedOrConnecting } ?: false
        }
    }

    fun getIp(): String {
        val context = AppContext.applicationContext
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val ipAddress = wifiManager.dhcpInfo.ipAddress
        val wifiIp = convertIPToString(ipAddress)

        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val network = connectivityManager.activeNetwork
        val linkProperties = connectivityManager.getLinkProperties(network)
        // Check if Ethernet is available
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkInterfaces = NetworkInterface.getNetworkInterfaces()
            while (networkInterfaces.hasMoreElements()) {
                val networkInterface = networkInterfaces.nextElement()
                if (networkInterface.name.startsWith("eth")) {
                    val inetAddresses = networkInterface.inetAddresses
                    while (inetAddresses.hasMoreElements()) {
                        val inetAddress = inetAddresses.nextElement()
                        if (inetAddress is Inet4Address) {
                            return inetAddress.hostAddress
                        }
                    }
                }
            }
        } else {
            linkProperties?.let { properties ->
                for (address in properties.linkAddresses) {
                    if (address.address is Inet4Address) {
                        val ip = address.address.hostAddress
                        if (ip.isNotEmpty() && ip != "0.0.0.0") {
                            return ip
                        }
                    }
                }
            }
        }
        return wifiIp
    }

    fun getNetmask(): String {
        val wifiManager = AppContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val netmask = wifiManager.dhcpInfo.netmask
        return convertIPToString(netmask)
    }

    fun getGateway(): String {
        val wifiManager = AppContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val gateway = wifiManager.dhcpInfo.gateway
        return convertIPToString(gateway)
    }

    fun getDns1(): String {
        val wifiManager = AppContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val dns1 = wifiManager.dhcpInfo.dns1
        return convertIPToString(dns1)
    }

    fun getDns2(): String {
        val wifiManager = AppContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val dns2 = wifiManager.dhcpInfo.dns2
        return convertIPToString(dns2)
    }

    fun printNetworkInfo() {
        LogUtils.d(TAG, "NetworkInfo IP Address: ${getIp()}")
        LogUtils.d(TAG, "NetworkInfo Network Mask: ${getNetmask()}")
        LogUtils.d(TAG, "NetworkInfo Gateway: ${getGateway()}")
        LogUtils.d(TAG, "NetworkInfo DNS 1: ${getDns1()}")
        LogUtils.d(TAG, "NetworkInfo DNS 2: ${getDns2()}")
    }

    fun convertIPToString(ip: Int): String {
        return String.format(
            "%d.%d.%d.%d",
            ip and 0xff,
            ip shr 8 and 0xff,
            ip shr 16 and 0xff,
            ip shr 24 and 0xff
        )
    }
}